#ifndef VD_CREATE_DEVICE
#define VD_CREATE_DEVICE

# include "vd.h"

NTSTATUS VD_CreateDevice (
    IN PDRIVER_OBJECT   DriverObject,
    IN LONG            Number
    )
{
    WCHAR						device_name_buffer[MAXIMUM_FILENAME_LENGTH];
    UNICODE_STRING			    device_name;
    NTSTATUS					status;
    PDEVICE_OBJECT				device_object;
    PDEVICE_EXTENSION			device_extension;
    HANDLE						thread_handle;
    
	status = RtlStringCchPrintfW(device_name_buffer, 
					sizeof(device_name_buffer)/sizeof(device_name_buffer[0]), 
					L"%ws%u", 
					DEVICE_NAME_PREFIX, Number
					);

	RtlInitUnicodeString(&device_name, device_name_buffer);

	status = IoCreateDevice(
							DriverObject,
							sizeof(DEVICE_EXTENSION),
							&device_name,
							FILE_DEVICE_DISK,
							0,
							FALSE,
							&device_object
						   );

	if (!NT_SUCCESS(status))
    {
		DbgPrint("Can't create device \n");
		return status;
	}
	
	DiskDeviceStatus[Number] = L'1';

	ClearFlag(device_object->Flags, DO_DEVICE_INITIALIZING);
	SetFlag(device_object->Flags, DO_DIRECT_IO);
	
	device_extension = (PDEVICE_EXTENSION) device_object->DeviceExtension;
	device_extension->DeviceNumber = Number;
	device_extension->disk_mounted = FALSE;

    InitializeListHead(&device_extension->list_head);

    KeInitializeSpinLock(&device_extension->list_lock);

    KeInitializeEvent(
					&device_extension->request_event,
					SynchronizationEvent,
					FALSE
					);

    device_extension->terminate_thread = FALSE;

    status = PsCreateSystemThread(
								&thread_handle,
								(ACCESS_MASK) 0L,
								NULL,
								NULL,
								NULL,
								VD_ThreadHandler,
								device_object
								);
    if (!NT_SUCCESS(status))
    {
		IoDeleteDevice(device_object);
        return status;
    }

    status = ObReferenceObjectByHandle(
									thread_handle,
									THREAD_ALL_ACCESS,
									NULL,
									KernelMode,
									&device_extension->thread_pointer,
									NULL
									  );
	
    if (!NT_SUCCESS(status))
    {
        ZwClose(thread_handle);

        device_extension->terminate_thread = TRUE;

        KeSetEvent(
				  &device_extension->request_event,
				  (KPRIORITY) 0,
				  FALSE
				  );

        IoDeleteDevice(device_object);

        return status;
    }
	
    ZwClose(thread_handle);
    return STATUS_SUCCESS;
}

# endif